package jrain.fw.http.fileupload;

import java.io.File;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import jrain.fw.core.business.BusinessConst;
import jrain.fw.core.business.BusinessRequest;
import jrain.fw.core.utils.FwUtils;
import jrain.utils.lang.StringUtils;
import jrain.utils.url.UrlUtils;

public class FileUploadUitls {

	private static volatile String home = null;

	public static void paraseRquest(BusinessRequest request) throws Exception {
		paraseRquest(request, null);
	}

	public static void paraseRquest(BusinessRequest request, Map<String, File> fileMap) throws Exception {
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload diskFileUpload = new ServletFileUpload(factory);
		HttpServletRequest httpRequest = (HttpServletRequest) request.getExtData(BusinessConst.EXT_REQUEST);
		List<FileItem> list = diskFileUpload.parseRequest((HttpServletRequest) httpRequest);
		List<FileItem> files = new ArrayList<>();
		// 表单字段
		final Map<String, Object> formData = new HashMap<>();
		for (FileItem fileItem : list) {
			if (fileItem.isFormField()) {
				String filedName = fileItem.getFieldName();
				formData.put(filedName, fileItem.getString());
			} else {
				files.add(fileItem);
			}
		}
		// 解析需要的参数
		String paramType = StringUtils.trimNull(formData.get(BusinessConst.REQ_PARAM_TYPE));
		String params = StringUtils.trimNull(formData.get(BusinessConst.REQ_PARAMS));
		// 普通参数
		if (StringUtils.isEmpty(paramType)) {
			// 默认参数类型
			if (!StringUtils.isEmpty(params)) {
				Map<String, Object> dataMap = FwUtils.getJsonService().toMap(params);
				request.setData(dataMap);
			}
		} else if (paramType.startsWith(BusinessConst.REQ_PARAM_PRE)) {
			// 前缀参数类型
			String preData = paramType.substring(4);
			int preDataLength = preData.length() + 1;
			Set<String> names = formData.keySet();
			for (String name : names) {
				if (name.startsWith(preData + "_") && name.length() >= preDataLength) {
					String key = name.substring(preDataLength);
					Object value = formData.get(name);
					request.putData(key, value);
				}
			}
		}
		if (fileMap != null) {
			for (FileItem fileItem : files) {
				String fieldName = fileItem.getFieldName();
				File file = fileMap.get(fieldName);
				if (file != null) {
					fileItem.write(file);
				}
			}
		}
		request.putExtData(BusinessConst.EXT_FILES, files);
	}

	public static String getFileName(BusinessRequest request, String fieldName) {
		FileItem fileItem = getFileItem(request, fieldName);
		return fieldName != null ? fileItem.getName() : null;
	}

	public static FileItem getFileItem(BusinessRequest request, String fieldName) {
		@SuppressWarnings("unchecked")
		List<FileItem> list = (List<FileItem>) request.getExtData(BusinessConst.EXT_FILES);
		for (FileItem fileItem : list) {
			if (fieldName.equals(fileItem.getFieldName())) {
				return fileItem;
			}
		}
		return null;
	}

	public static void saveFileByPath(BusinessRequest request, String fieldName, String path) throws Exception {
		if (home != null) {
			home = StringUtils.trimNull(FwUtils.getCfgService().getCfgValue("upload", "upload.dir"));
		}
		String fullPath = UrlUtils.joinUrl(home, path);
		saveFileByFullPath(request, fieldName, fullPath);
	}

	public static void saveFileByFullPath(BusinessRequest request, String fieldName, String path) throws Exception {
		saveFileByFile(request, fieldName, new File(path));
	}

	public static void saveFileByFile(BusinessRequest request, String fieldName, File file) throws Exception {
		@SuppressWarnings("unchecked")
		List<FileItem> list = (List<FileItem>) request.getExtData(BusinessConst.EXT_FILES);
		for (FileItem fileItem : list) {
			if (fieldName.equals(fileItem.getFieldName())) {
				file.getParentFile().mkdirs();
				fileItem.write(file);
				break;
			}
		}
	}

	public static void saveFileByOutput(BusinessRequest request, String fieldName, OutputStream output) {

	}

}
